package com.music.mysongs.file

import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.*
import java.net.HttpURLConnection
import java.net.MalformedURLException
import java.net.URL
import java.util.*


class FileUpload {
    private val RequestURL: String? = null//"http://192.168.0.100:7080/YkyPhoneService/Uploadfile1"

    fun uploadFile(
        file: File?,
        code: Int,//成功响应20000
        httpKey: String,//网址key
        fileName: String,//文件名包后缀
        fileType: String//文件类型img
    ): Boolean {
        val TIME_OUT = 10 * 10000000 // 超时时间
        val CHARSET = "utf-8" // 设置编码
        val BOUNDARY: String = UUID.randomUUID().toString() // 边界标识 随机生成
        val PREFIX = "--"
        val LINE_END = "\r\n"
        val CONTENT_TYPE = "multipart/form-data" // 内容类型
        try {
            val url = URL(RequestURL)
            val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
            conn.readTimeout = TIME_OUT
            conn.connectTimeout = TIME_OUT
            conn.doInput = true // 允许输入流
            conn.doOutput = true // 允许输出流
            conn.useCaches = false // 不允许使用缓存
            conn.requestMethod = "POST" // 请求方式
            conn.setRequestProperty("Charset", CHARSET) // 设置编码
            conn.setRequestProperty("connection", "keep-alive")
            conn.setRequestProperty(
                "Content-Type", CONTENT_TYPE + ";boundary="
                        + BOUNDARY
            )
            if (file != null) {
                /**
                 * 当文件不为空，把文件包装并且上传
                 */
                val outputSteam: OutputStream = conn.outputStream
                val dos = DataOutputStream(outputSteam)
                val sb = StringBuffer()
                sb.append(PREFIX)
                sb.append(BOUNDARY)
                sb.append(LINE_END)
                /**
                 * 这里重点注意： name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件
                 * filename是文件的名字，包含后缀名的 比如:abc.png
                 */
                sb.append(
                    "Content-Disposition: form-data; $httpKey=\"$fileType\"; $fileName=\""
                            + file.name + "\"" + LINE_END
                )
                sb.append(
                    ("Content-Type: application/octet-stream; charset="
                            + CHARSET) + LINE_END
                )
                sb.append(LINE_END)
                dos.write(sb.toString().toByteArray())
                val `is`: InputStream = FileInputStream(file)
                val bytes = ByteArray(1024)
                var len: Int
                while (`is`.read(bytes).also { len = it } != -1) {
                    dos.write(bytes, 0, len)
                }
                `is`.close()
                dos.write(LINE_END.toByteArray())
                val endData = (PREFIX + BOUNDARY + PREFIX + LINE_END)
                    .toByteArray()
                dos.write(endData)
                dos.flush()
                val res: Int = conn.responseCode
                if (res == code) {
                    return true
                }
            }
        } catch (e: MalformedURLException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return false
    }

    private fun uploadWebFile(uploadUrl: String) {
        val uploadFile = "/sdcard/testimg.jpg";
        val srcPath = "/sdcard/testimg.jpg";
        // 服务器上接收文件的处理页面，这里根据需要换成自己的
        val actionUrl = "http://10.100.1.208/receive_file.php";
        val end = "\r\n"
        val twoHyphens = "--"
        val boundary = "******"
        try {
            val url = URL(uploadUrl)
            val httpURLConnection = url
                .openConnection() as HttpURLConnection
            // 设置每次传输的流大小，可以有效防止手机因为内存不足崩溃
            // 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。
            httpURLConnection.setChunkedStreamingMode(128 * 1024) // 128K
            // 允许输入输出流
            httpURLConnection.doInput = true
            httpURLConnection.doOutput = true
            httpURLConnection.useCaches = false
            // 使用POST方法
            httpURLConnection.requestMethod = "POST"
            httpURLConnection.setRequestProperty("Connection", "Keep-Alive")
            httpURLConnection.setRequestProperty("Charset", "UTF-8")
            httpURLConnection.setRequestProperty(
                "Content-Type",
                "multipart/form-data;boundary=$boundary"
            )
            val dos = DataOutputStream(
                httpURLConnection.outputStream
            )
            dos.writeBytes(twoHyphens + boundary + end)
            dos.writeBytes(
                ("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\""
                        + srcPath.substring(srcPath.lastIndexOf("/") + 1)
                        ) + "\"" + end
            )
            dos.writeBytes(end)
            val fis = FileInputStream(srcPath)
            val buffer = ByteArray(8192) // 8k
            var count = 0
            // 读取文件
            while (fis.read(buffer).also { count = it } != -1) {
                dos.write(buffer, 0, count)
            }
            fis.close()
            dos.writeBytes(end)
            dos.writeBytes(twoHyphens + boundary + twoHyphens + end)
            dos.flush()
            val `is` = httpURLConnection.inputStream
            val isr = InputStreamReader(`is`, "utf-8")
            val br = BufferedReader(isr)
            val result = br.readLine()
            dos.close()
            `is`.close()
        } catch (e: Exception) {
            e.printStackTrace()
            e.message
        }
    }

    /**
     * @param mediaType MediaType
     * @param uploadUrl put请求地址
     * @param localPath 本地文件路径
     * @return 响应的结果 和 HTTP status code
     * @throws IOException
     */
    @Throws(IOException::class)
    fun putFile(mediaType: MediaType?, uploadUrl: String?, localPath: String): String? {
        val client = OkHttpClient()
        val file = File(localPath)
        val body: RequestBody = file.asRequestBody(mediaType)
        val request = Request.Builder()
            .url(uploadUrl!!)
            .post(body)
            .build()
        val response: Response = client.newCall(request).execute()
        return response.code.toString() + ":" + response.body!!.string()
    }

    //上传JPG图片
    @Throws(IOException::class)
    fun putImg(uploadUrl: String?, localPath: String): String? {
        val Image: MediaType = "image/jpeg; charset=utf-8".toMediaTypeOrNull()!!
        return putFile(Image, uploadUrl, localPath)
    }
}